package com.lastproject.web.bean;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import com.lastproject.dto.CandidateDTO;
import com.lastproject.dto.ConfidentialEmployeeDTO;
import com.lastproject.dto.DepartmentDTO;
import com.lastproject.dto.EmployeeDTO;
import com.lastproject.dto.TraineeDTO;
import com.lastproject.dto.UserDTO;
import com.lastproject.ejb.dao.CandidateDAORemote;
import com.lastproject.ejb.dao.ConfidentialEmployeeDAORemote;
import com.lastproject.ejb.dao.DepartmentDAORemote;
import com.lastproject.ejb.dao.EmployeeDAORemote;
import com.lastproject.ejb.dao.TraineeDAORemote;
import com.lastproject.ejb.dao.UserDAORemote;

@ManagedBean
@SessionScoped
public class EmployeeBean implements Validator {

	private boolean basicUser = false; // id 1
	private boolean teamLeader = false; // id 2
	private boolean administration = false; // id 3
	private boolean departmentManager = false; // id 4
	private boolean libraryAdmin = false; // id 5
	private boolean accountant = false; // id 7

	private List<Integer> roleIdList = new ArrayList<Integer>();

	private List<EmployeeDTO> teamLeaderList;
	private List<DepartmentDTO> departmentList;
	private List<UserDTO> superiorList;
	private int selectedTeamLeaderId;
	private int selectedDepartmentId;
	private int selectedSuperiorId;

	private boolean renderSalary;

	private int idEmployee;

	private String errorMessage;
	private String departmentManagerMessage;
	
	private String updateType = null;

	// private
	
	private CandidateDTO candidateDTO;

	@ManagedProperty(value = "#{confidentialEmployeeDTO}")
	private ConfidentialEmployeeDTO confidentialEmployeeDTO;

	// @ManagedProperty(value = "#{forAddUserDTO}")
	// private UserDTO forAddUserDTO;

	@ManagedProperty(value = "#{traineeDTO}")
	private TraineeDTO traineeDTO;

	public CandidateDTO getCandidateDTO() {
		return candidateDTO;
	}

	public void setCandidateDTO(CandidateDTO candidateDTO) {
		this.candidateDTO = candidateDTO;
	}

	public String getUpdateType() {
		return updateType;
	}

	public void setUpdateType(String updateType) {
		this.updateType = updateType;
	}

	@EJB
	EmployeeDAORemote employeeDAORemote;

	@EJB
	ConfidentialEmployeeDAORemote confidentialEmployeeDAORemote;

	@EJB
	UserDAORemote userDAORemote;

	@EJB
	TraineeDAORemote traineeDAORemote;

	@EJB
	DepartmentDAORemote departmentDAORemote;
	
	@EJB
	CandidateDAORemote candidateDAORemote;

	@PostConstruct
	public void populateLists() {

		teamLeaderList = employeeDAORemote.getTeamLeaders();
		departmentList = departmentDAORemote.getAll();
		superiorList = userDAORemote.getAll();

		renderSalary = true;
	}

	public EmployeeBean() {
	}

	public int getIdEmployee() {
		return idEmployee;
	}

	public void setIdEmployee(int idEmployee) {
		this.idEmployee = idEmployee;
	}

	// public EmployeeDTO getEmployeeDTO() {
	// return employeeDTO;
	// }
	//
	// public void setEmployeeDTO(EmployeeDTO employeeDTO) {
	// this.employeeDTO = employeeDTO;
	// }

	public ConfidentialEmployeeDTO getConfidentialEmployeeDTO() {
		return confidentialEmployeeDTO;
	}

	public void setConfidentialEmployeeDTO(
			ConfidentialEmployeeDTO confidentialEmployeeDTO) {
		this.confidentialEmployeeDTO = confidentialEmployeeDTO;
	}

	// public UserDTO getForAddUserDTO() {
	// return forAddUserDTO;
	// }
	//
	// public void setForAddUserDTO(UserDTO forAddUserDTO) {
	// this.forAddUserDTO = forAddUserDTO;
	// }

	public TraineeDTO getTraineeDTO() {
		return traineeDTO;
	}

	public void setTraineeDTO(TraineeDTO traineeDTO) {
		this.traineeDTO = traineeDTO;
	}

	public boolean isBasicUser() {
		return basicUser;
	}

	public void setBasicUser(boolean basicUser) {
		this.basicUser = basicUser;
	}

	public boolean isAdministration() {
		return administration;
	}

	public void setAdministration(boolean administration) {
		this.administration = administration;
	}

	public boolean isDepartmentManager() {
		return departmentManager;
	}

	public void setDepartmentManager(boolean departmentManager) {
		this.departmentManager = departmentManager;
	}

	public boolean isLibraryAdmin() {
		return libraryAdmin;
	}

	public void setLibraryAdmin(boolean libraryAdmin) {
		this.libraryAdmin = libraryAdmin;
	}

	public boolean isTeamLeader() {
		return teamLeader;
	}

	public void setTeamLeader(boolean teamLeader) {
		this.teamLeader = teamLeader;
	}

	public boolean isAccountant() {
		return accountant;
	}

	public void setAccountant(boolean accountant) {
		this.accountant = accountant;
	}

	public boolean isRenderSalary() {
		return renderSalary;
	}

	public void setRenderSalary(boolean renderSalary) {
		this.renderSalary = renderSalary;
	}

	public List<EmployeeDTO> getTeamLeaderList() {
		populateLists();
		return teamLeaderList;
	}

	public List<DepartmentDTO> getDepartmentList() {
		populateLists();
		return departmentList;
	}

	public int getSelectedTeamLeaderId() {
		return selectedTeamLeaderId;
	}

	public void setSelectedTeamLeaderId(int selectedTeamLeaderId) {
		this.selectedTeamLeaderId = selectedTeamLeaderId;
	}

	public int getSelectedDepartmentId() {
		return selectedDepartmentId;
	}

	public void setSelectedDepartmentId(int selectedDepartmentId) {
		this.selectedDepartmentId = selectedDepartmentId;
	}

	public List<UserDTO> getSuperiorList() {
		populateLists();
		return superiorList;
	}

	public int getSelectedSuperiorId() {
		return selectedSuperiorId;
	}

	public void setSelectedSuperiorId(int selectedSuperiorId) {
		this.selectedSuperiorId = selectedSuperiorId;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public String getDepartmentManagerMessage() {
		return departmentManagerMessage;
	}

	public void setDepartmentManagerMessage(String departmentManagerMessage) {
		this.departmentManagerMessage = departmentManagerMessage;
	}

	/**
	 * adds a confidentionalEmployee OR Trainee in the database
	 * 
	 * @return null string
	 */
	public String addEmployee() {

		for (EmployeeDTO tl : teamLeaderList) {
			System.out.println(" tllist > " + tl.getUsername());
		}

		for (DepartmentDTO tl : departmentList) {
			System.out.println(" deplist > " + tl.getName());
		}

		System.out.println("selected team leader id >" + selectedTeamLeaderId
				+ " selected dep id >" + selectedDepartmentId
				+ " selected superior (user) id >" + selectedSuperiorId);

		FacesContext ctx = FacesContext.getCurrentInstance();
		ExternalContext ectx = ctx.getExternalContext();
		HttpServletRequest request = (HttpServletRequest) ectx.getRequest();

		String userType = request.getParameter("cicic");
		System.out.println("type  >>>>" + userType);

		System.out.println("before uploadCV");

		try {

			System.out.println("uploadCV");

			Enumeration<String> e = request.getParameterNames();
			while (e.hasMoreElements()) {
				System.out.println(e.nextElement());
			}

			InputStream is = request.getPart("formAddUser:uploadedFile")
					.getInputStream();
			int i = is.available();
			byte[] b = new byte[i];

			is.read(b);
		

			switch (userType) {

			case "employee":
				System.out.println("Case employee!!!!");
//				confidentialEmployeeDTO.setEnabled(true);

				if (b.length != 0) {
					// add
					confidentialEmployeeDTO.setCv(b);
				} else {
					// update
					System.out.println("CV exists");

				}

				// confidentialEmployeeDTO.setIdTeamLeader(selectedTeamLeaderId);
				confidentialEmployeeDTO.setIdDepartment(selectedDepartmentId);
				confidentialEmployeeDTO.setIdSuperior(selectedSuperiorId);

				if (basicUser) {
					System.out.println("selected basicUser");
					roleIdList.add(1);
				} else {
					if(roleIdList.contains(1)) {
						roleIdList.remove(roleIdList.indexOf(1));
					}
				}
				

				if (selectedTeamLeaderId == 0) {
					// employee has team lead role
					System.out.println("selected teamLeader in combobox");
					confidentialEmployeeDTO.setTeamLeader(true);
					roleIdList.add(2);
				} else {
					// employee has a team lead
					confidentialEmployeeDTO
							.setIdTeamLeader(selectedTeamLeaderId);
					
					if(roleIdList.contains(2)) {
						roleIdList.remove(roleIdList.indexOf(2));
					}
				}

				// if (teamLeader) {
				// System.out.println("selected teamLeader");
				// confidentialEmployeeDTO.setTeamLeader(true);
				// roleIdList.add(2);
				// }

				if (administration) {
					System.out.println("selected administration");
					roleIdList.add(3);
				} else {
					if(roleIdList.contains(3)) {
						roleIdList.remove(roleIdList.indexOf(3));
					}
				}

				if (departmentManager) {
					System.out.println("selected departmentManager");
					confidentialEmployeeDTO.setDepartmentManager(true);
					roleIdList.add(4);
				} else {
					if(roleIdList.contains(4)) {
						roleIdList.remove(roleIdList.indexOf(4));
					}
				}

				if (libraryAdmin) {
					System.out.println("selected libraryAdmin");
					roleIdList.add(5);
				} else {
					if(roleIdList.contains(5)) {
						roleIdList.remove(roleIdList.indexOf(5));
					}
				}

				if (accountant) {
					System.out.println("selected accountant");
					roleIdList.add(7);
				} else {
					if(roleIdList.contains(7)) {
						roleIdList.remove(roleIdList.indexOf(7));
					}
				}

				System.out
						.println("Length list of roles: " + roleIdList.size());
				confidentialEmployeeDTO.setRolesIdList(roleIdList);

				if (confidentialEmployeeDAORemote
						.findById(confidentialEmployeeDTO.getId()) != null) {
					// user with given id is found in db
					// edit their info
					System.out.println("Update case");
					confidentialEmployeeDAORemote.edit(confidentialEmployeeDTO);
					updateType = null;
					// confidentialEmployeeDAORemote.edit(confidentialEmployeeDTO);
				} 

				else 

				{
					// user with given id is not found
					// add it
					confidentialEmployeeDTO.setPassword(confidentialEmployeeDTO
							.getUsername());
					confidentialEmployeeDTO.setStatusPassword("newPassword");
					confidentialEmployeeDTO.setEnabled(false);
					confidentialEmployeeDAORemote
					.create(confidentialEmployeeDTO);
					System.out.println("Add case");
				}

				// reset all fields
				confidentialEmployeeDTO.setUsername(null);
				confidentialEmployeeDTO.setFirstname(null);
				confidentialEmployeeDTO.setLastname(null);
				confidentialEmployeeDTO.setWorkEmail(null);
				confidentialEmployeeDTO.setDob(null);
				confidentialEmployeeDTO.setPersonalPhone(null);
				confidentialEmployeeDTO.setPersonalEmail(null);
				confidentialEmployeeDTO.setEmploymentDate(null);
				confidentialEmployeeDTO.setMedCheckUpDate(null);
				confidentialEmployeeDTO.setEmploymentType(null);
				confidentialEmployeeDTO.setPosition(null);

				confidentialEmployeeDTO.setCareerLevel(null);
				confidentialEmployeeDTO.setGermanContactPerson(null);
				confidentialEmployeeDTO.setProsisNr(0);
				confidentialEmployeeDTO.setWorkPhone(null);

				confidentialEmployeeDTO.setSalary(null);
				confidentialEmployeeDTO.setVarPart(null);

				break;

			case "trainee":
				System.out.println("Case traineee!!");

				traineeDTO.setCv(b);

//				traineeDTO.setEnabled(true);

				if (basicUser) {
					System.out.println("selected basicUser");
					roleIdList.add(1);
				}

				traineeDTO.setRolesIdList(roleIdList);

				// traineeDAORemote.create(traineeDTO);

				if (traineeDAORemote.findById(traineeDTO.getId()) != null) {
					// user with given id is found in db
					// edit their info
					System.out.println("Update case");
					traineeDAORemote.edit(traineeDTO);
					// confidentialEmployeeDAORemote.edit(confidentialEmployeeDTO);
				} else {
					// user with given id is not found
					// add it
					traineeDTO.setPassword(traineeDTO.getUsername());
					traineeDTO.setStatusPassword("newPassword");
					traineeDTO.setEnabled(false);
					traineeDAORemote.create(traineeDTO);
					System.out.println("Add case");
				}

				// reset all fields
				traineeDTO.setUsername(null);
				traineeDTO.setFirstname(null);
				traineeDTO.setLastname(null);
				traineeDTO.setWorkEmail(null);
				traineeDTO.setDob(null);
				traineeDTO.setPersonalPhone(null);
				traineeDTO.setPersonalEmail(null);
				traineeDTO.setEmploymentDate(null);
				// traineeDTO.setDepartureDate(null);
				traineeDTO.setMedCheckUpDate(null);
				traineeDTO.setEmploymentType(null);
				traineeDTO.setPosition(null);

				traineeDTO.setSalary(null);

				break;
			default:
				System.out.println("DEFAULT!!");
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ServletException e) {
			e.printStackTrace();
		}
		return null;
	}

	public String updateUsers() {

		FacesContext ctx = FacesContext.getCurrentInstance();
		ExternalContext ectx = ctx.getExternalContext();
		HttpServletRequest request = (HttpServletRequest) ectx.getRequest();

		int id = Integer.parseInt(request.getParameter("updateId"));
		updateType = request.getParameter("updateType");

//		request.setAttribute("updateType", updateType);

		System.out.println("idforupdate = " + id);
		System.out.println("typeforupdate = " + updateType);

		String returnPage = "";

		switch (updateType) {

		case "ConfidentialEmployee":

			System.out.println("update case confidentialemployee");
			ConfidentialEmployeeDTO c = confidentialEmployeeDAORemote
					.findById(id);

			confidentialEmployeeDTO.setId(c.getId());
			confidentialEmployeeDTO.setFirstname(c.getFirstname());
			confidentialEmployeeDTO.setLastname(c.getLastname());
			confidentialEmployeeDTO.setUsername(c.getUsername());
			confidentialEmployeeDTO.setPassword(c.getPassword());
			confidentialEmployeeDTO.setEnabled(c.isEnabled());
			confidentialEmployeeDTO.setWorkEmail(c.getWorkEmail());
			confidentialEmployeeDTO.setDob(c.getDob());
			confidentialEmployeeDTO.setPersonalPhone(c.getPersonalPhone());
			confidentialEmployeeDTO.setPersonalEmail(c.getPersonalEmail());
			confidentialEmployeeDTO.setEmploymentDate(c.getEmploymentDate());
			confidentialEmployeeDTO.setMedCheckUpDate(c.getMedCheckUpDate());
			confidentialEmployeeDTO.setEmploymentType(c.getEmploymentType());
			confidentialEmployeeDTO.setPosition(c.getPosition());
			confidentialEmployeeDTO.setCv(c.getCv());
			confidentialEmployeeDTO.setProsisNr(c.getProsisNr());
			confidentialEmployeeDTO.setWorkPhone(c.getWorkPhone());
			confidentialEmployeeDTO.setGermanContactPerson(c
					.getGermanContactPerson());
			confidentialEmployeeDTO.setCareerLevel(c.getCareerLevel());
			confidentialEmployeeDTO.setRolesIdList(c.getRolesIdList());
			confidentialEmployeeDTO.setSalary(c.getSalary());
			confidentialEmployeeDTO.setVarPart(c.getVarPart());

			selectedTeamLeaderId = c.getIdTeamLeader();
			selectedDepartmentId = c.getIdDepartment();
			selectedSuperiorId = c.getIdSuperior();

			roleIdList = confidentialEmployeeDTO.getRolesIdList();

			if (roleIdList.size() != 0) {
				for (int i = 0; i < roleIdList.size(); i++) {
					System.out.println("Employee Roles ids "
							+ roleIdList.get(i));
					if (roleIdList.get(i) == 1) {
						basicUser = true;
					} else if (roleIdList.get(i) == 2) {
						teamLeader = true;
					} else if (roleIdList.get(i) == 3) {
						administration = true;
					} else if (roleIdList.get(i) == 4) {
						departmentManager = true;
					} else if (roleIdList.get(i) == 5) {
						libraryAdmin = true;
					} else if (roleIdList.get(i) == 7) {
						accountant = true;
					}
				}
			} else {
				System.out.println("No roles here");
			}

			returnPage = "addEmployee";
			break;

		case "Trainee":

			System.out.println("update case trainee");

			TraineeDTO t = traineeDAORemote.findById(id);

			traineeDTO.setId(t.getId());
			traineeDTO.setFirstname(t.getFirstname());
			traineeDTO.setLastname(t.getLastname());
			traineeDTO.setUsername(t.getUsername());
			traineeDTO.setPassword(t.getPassword());
			traineeDTO.setEnabled(t.isEnabled());
			traineeDTO.setWorkEmail(t.getWorkEmail());
			traineeDTO.setDob(t.getDob());
			traineeDTO.setPersonalPhone(t.getPersonalPhone());
			traineeDTO.setPersonalEmail(t.getPersonalEmail());
			traineeDTO.setEmploymentDate(t.getEmploymentDate());
			traineeDTO.setMedCheckUpDate(t.getMedCheckUpDate());
			traineeDTO.setEmploymentType(t.getEmploymentType());
			traineeDTO.setPosition(t.getPosition());

			traineeDTO.setCv(t.getCv());

			traineeDTO.setSalary(t.getSalary());
			traineeDTO.setRolesIdList(t.getRolesIdList());
			traineeDTO.setSalary(t.getSalary());

			roleIdList = traineeDTO.getRolesIdList();

			if (roleIdList.size() != 0) {
				for (int i = 0; i < roleIdList.size(); i++) {
					System.out.println(" Trainee Roles ids "
							+ roleIdList.get(i));

					if (roleIdList.get(i) == 1) {
						basicUser = true;
					} else if (roleIdList.get(i) == 2) {
						teamLeader = true;
					} else if (roleIdList.get(i) == 3) {
						administration = true;
					} else if (roleIdList.get(i) == 4) {
						departmentManager = true;
					} else if (roleIdList.get(i) == 5) {
						libraryAdmin = true;
					} else if (roleIdList.get(i) == 7) {
						accountant = true;
						System.out.println("accountant " + accountant);
					}
				}
			} else {
				System.out.println("No roles here");
			}

			returnPage = "addTrainee";
			break;

		}
		return returnPage;
	}

	/**
	 * Validates the upload PDF form field
	 */
	@Override
	public void validate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {

		FacesContext ctx = FacesContext.getCurrentInstance();
		ExternalContext ectx = ctx.getExternalContext();
		HttpServletRequest request = (HttpServletRequest) ectx.getRequest();
		
//		updateType = (String) request.getAttribute("updateType");
		System.out.println("In validator, value is: " + updateType);

		List<FacesMessage> msgs = new ArrayList<FacesMessage>();
		Part file = (Part) value;

		errorMessage = "";

		if (!"application/pdf".equals(file.getContentType())) {
			if (updateType == null) {
				msgs.add(new FacesMessage("not a pdf"));
				errorMessage = "Not a pdf";
			} else {
				// this is update
				errorMessage = "";
			}
		}

		if (!msgs.isEmpty()) {
			throw new ValidatorException(msgs);
		}

	}

	// public void validateDepartmentManager(FacesContext context,
	// UIComponent component, Object value) throws ValidatorException {
	//
	// List<FacesMessage> msgs = new ArrayList<FacesMessage>();
	//
	// departmentManagerMessage = "";
	//
	// if (confidentialEmployeeDAORemote
	// .checkIfDeparmentHasManager(selectedDepartmentId)) {
	// departmentManagerMessage = "Selected department already has a manager";
	// }
	//
	// if (!msgs.isEmpty()) {
	// throw new ValidatorException(msgs);
	// }
	// }

	// public String addEmployeePage() {
	//
	// String firstname = FacesContext.getCurrentInstance()
	// .getExternalContext().getRequestParameterMap().get("firstname");
	// String lastname = FacesContext.getCurrentInstance()
	// .getExternalContext().getRequestParameterMap().get("lastname");
	//
	// CandidateDTO candidateDTO;
	//
	// candidateDTO = candidateDAORemote.findByFullName(firstname, lastname);
	//
	// confidentialEmployeeDTO = new ConfidentialEmployeeDTO();
	//
	// confidentialEmployeeDTO.setFirstname(candidateDTO.getFirstname());
	// confidentialEmployeeDTO.setLastname(candidateDTO.getLastname());
	// confidentialEmployeeDTO.setDob(candidateDTO.getBirthdate());
	// confidentialEmployeeDTO.setPersonalPhone(candidateDTO.getPhoneNr());
	// confidentialEmployeeDTO.setPersonalEmail(candidateDTO.getEmail());
	//
	// return "addEmployee";
	// }

	public String addEmployeePage() {
		String id = FacesContext.getCurrentInstance().getExternalContext()
				.getRequestParameterMap().get("id");

		

		candidateDTO = candidateDAORemote.findById(Integer.parseInt(id));
		candidateDTO.setStatut("accepted");

		candidateDAORemote.edit(candidateDTO);

		String firstname = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestParameterMap().get("firstname");
		String lastname = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestParameterMap().get("lastname");

		candidateDTO = candidateDAORemote.findByFullName(firstname, lastname);

		// confidentialEmployeeDTO = new ConfidentialEmployeeDTO();

		confidentialEmployeeDTO.setFirstname(candidateDTO.getFirstname());
		confidentialEmployeeDTO.setLastname(candidateDTO.getLastname());
		confidentialEmployeeDTO.setDob(candidateDTO.getBirthdate());
		confidentialEmployeeDTO.setPersonalPhone(candidateDTO.getPhoneNr());
		confidentialEmployeeDTO.setPersonalEmail(candidateDTO.getEmail());

		System.out.println("NUMEEEEE->: "
				+ confidentialEmployeeDTO.getFirstname());

		

		return "addEmployee";
	}

}
